package com.ls.herostory.login;

import com.ls.herostory.thread.AsyncOperationProcessor;
import com.ls.herostory.thread.AsyncOperation;
import com.ls.herostory.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Consumer;

/**
 * @author liangsu
 * @version v1.0
 * @Description
 * @Date 2020/10/14 9:42
 * @since
 */
public class UserManager {
    private final static Logger logger = LoggerFactory.getLogger(UserManager.class);

    private static UserManager userManager = new UserManager();

    private UserManager(){
    }

    public static UserManager getInstance(){
        return userManager;
    }

    /**
     * 登陆用户，
     * 如果用户不不存在则新增
     * 如果用户存在则判断密码是否正确
     * @param userName
     * @param password
     * @param callback 回调方法
     * @return 登陆成功，返回User对象，登陆失败返回null
     */
    public void asyncLogin(String userName, String password, Consumer<User> callback){
        AsyncGetUser asyncGetUser = new AsyncGetUser(userName, password) {
            @Override
            public void doFinish() {
                if (callback != null) {
                    callback.accept(super.retUser);
                }
            }
        };

        // 异步执行
        AsyncOperationProcessor.getIntance().process(asyncGetUser);
    }

    abstract class AsyncGetUser implements AsyncOperation {
        private String userName;
        private String password;

        public AsyncGetUser(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }

        private User retUser;

        @Override
        public Integer getBindId() {
            return null;
        }

        @Override
        public void doAsync() {
            SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
            SqlSession sqlSession = sqlSessionFactory.openSession(false);
            try{
                UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

                User user = userMapper.getByUserName(userName);
                if(user != null){
                    if(user.getPassword() != null && !user.getPassword().equals(password)){
                        user = null;
                    }
                }else{
                    user = new User();
                    user.setUserName(userName);
                    user.setPassword(password);
                    user.setHeroAvatar("");
                    userMapper.save(user);
                }
                sqlSession.commit();

                retUser = user;
            }catch (Exception e){
                sqlSession.rollback();
                logger.error("", e);
            }finally {
                if(sqlSession != null){
                    sqlSession.close();
                }
            }
        }
    }

    public void asyncUpdateHero(Integer id, String heroAvatar, Consumer<Boolean> callback){
        AsyncOperation asyncOperation = new AsyncOperation() {
            // 是否更新成功
            boolean updateSucess = false;

            @Override
            public Integer getBindId() {
                return null;
            }

            @Override
            public void doAsync() {
                SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
                SqlSession sqlSession = sqlSessionFactory.openSession(false);
                try{
                    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

                    User user = userMapper.getById(id);
                    if(user != null){
                        user.setHeroAvatar(heroAvatar);
                        userMapper.update(user);
                        updateSucess = true;
                    }
                    sqlSession.commit();
                }catch (Exception e){
                    sqlSession.rollback();
                    logger.error("", e);
                }finally {
                    if(sqlSession != null){
                        sqlSession.close();
                    }
                }
            }

            @Override
            public void doFinish() {
                if (callback != null) {
                    callback.accept(updateSucess);
                }
            }
        };

        // 异步执行
        AsyncOperationProcessor.getIntance().process(asyncOperation);
    }


}
